package system;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

public class Unzip {
	public void doUnzip(String inputZip, String destinationDirectory)
	        throws IOException {
	    int BUFFER = 2048;
	    List<String> zipFiles = new ArrayList<String>();
	    File sourceZipFile = new File(inputZip);
	    File unzipDestinationDirectory = new File(destinationDirectory);
	    unzipDestinationDirectory.mkdir();

	    ZipFile zipFile;
	    // Open Zip file for reading
	    zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ);

	    // Create an enumeration of the entries in the zip file
	    Enumeration<? extends ZipEntry> zipFileEntries = zipFile.entries();

	    // Process each entry
	    while (zipFileEntries.hasMoreElements()) {
	        // grab a zip file entry
	        ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();

	        String currentEntry = entry.getName();

	        File destFile = new File(unzipDestinationDirectory, currentEntry);
	        destFile = new File(unzipDestinationDirectory, destFile.getName());

	        if (currentEntry.endsWith(".zip")) {
	            zipFiles.add(destFile.getAbsolutePath());
	        }

	        // grab file's parent directory structure
	        File destinationParent = destFile.getParentFile();

	        // create the parent directory structure if needed
	        destinationParent.mkdirs();

	        try {
	            // extract file if not a directory
	            if (!entry.isDirectory()) {
	                BufferedInputStream is =
	                        new BufferedInputStream(zipFile.getInputStream(entry));
	                int currentByte;
	                // establish buffer for writing file
	                byte data[] = new byte[BUFFER];

	                // write the current file to disk
	                FileOutputStream fos = new FileOutputStream(destFile);
	                BufferedOutputStream dest =
	                        new BufferedOutputStream(fos, BUFFER);

	                // read and write until last byte is encountered
	                while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
	                    dest.write(data, 0, currentByte);
	                }
	                dest.flush();
	                dest.close();
	                is.close();
	            }
	        } catch (IOException ioe) {
	            ioe.printStackTrace();
	        }
	    }
	    zipFile.close();

	    for (Iterator<String> iter = zipFiles.iterator(); iter.hasNext();) {
	        String zipName = (String)iter.next();
	        doUnzip(
	            zipName,
	            destinationDirectory +
	                File.separatorChar +
	                zipName.substring(0,zipName.lastIndexOf(".zip"))
	        );
	    }

	}

	static public void extractFileFromWeb(String zipFile, String newPath) throws ZipException, IOException
	{
	    System.out.println(zipFile);
	    String fileName = zipFile.substring( zipFile.lastIndexOf('/')+1, zipFile.length() );
	    String savedFilePath = newPath+"/"+fileName;
	    
		saveFileFromWeb(zipFile, savedFilePath);
	    extractFolderFromFile(savedFilePath, newPath);
	}
	
	static public void saveFileFromWeb(String filePath, String newPath) throws IOException {
	    URL website = new URL(filePath);
	    ReadableByteChannel rbc = Channels.newChannel(website.openStream());
	    
	    FileOutputStream fos = new FileOutputStream(newPath);
	    fos.getChannel().transferFrom(rbc, 0, 1 << 24);
	}
	
	static public void extractFolderFromFile(String fileName, String newPath) throws ZipException, IOException {
	    int BUFFER = 2048;
	    File file = new File(fileName);
	    ZipFile zip = new ZipFile(file);
	//    String newPath = zipFile.substring(0, zipFile.length() - 4);
	
	    new File(newPath).mkdir();
	    Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
	
	    // Process each entry
	    while (zipFileEntries.hasMoreElements())
	    {
	        // grab a zip file entry
	        ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
	        String currentEntry = entry.getName();
	        File destFile = new File(newPath, currentEntry);
	        //destFile = new File(newPath, destFile.getName());
	        File destinationParent = destFile.getParentFile();
	
	        // create the parent directory structure if needed
	        destinationParent.mkdirs();
	
	        if (!entry.isDirectory())
	        {
	            BufferedInputStream is = new BufferedInputStream(zip
	            .getInputStream(entry));
	            int currentByte;
	            // establish buffer for writing file
	            byte data[] = new byte[BUFFER];
	
	            // write the current file to disk
	            FileOutputStream fos = new FileOutputStream(destFile);
	            BufferedOutputStream dest = new BufferedOutputStream(fos,
	            BUFFER);
	
	            // read and write until last byte is encountered
	            while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
	                dest.write(data, 0, currentByte);
	            }
	            dest.flush();
	            dest.close();
	            is.close();
	        }
	    }
	}
}
